package com.ruoyi.system.aspect;

import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.BaseEntity;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.annotation.OperationScope;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * 运营中心数据过滤处理
 * 
 * @author SmapertZh
 */
@Aspect
@Component
public class OperationScopeAspect {
    
    /**
     * 运营中心数据权限过滤关键字
     */
    public static final String OPERATION_SCOPE = "operationScope";

    @Before("@annotation(controllerDataScope)")
    public void doBefore(JoinPoint point, OperationScope controllerDataScope) throws Throwable {
        clearDataScope(point);
        handleDataScope(point, controllerDataScope);
    }

    protected void handleDataScope(final JoinPoint joinPoint, OperationScope controllerDataScope) {
        // 获取运营中心id
        String operationId = SecurityUtils.getOperationId();
        if (StringUtils.isNotBlank(operationId)) {
            dataScopeFilter(joinPoint, Long.parseLong(operationId), controllerDataScope.tableAlias());
        }
    }

    /**
     * 数据范围过滤
     * 
     * @param joinPoint 切点
     * @param operationId 运营中心id
     * @param tableAlias 业务表别名
     */
    public static void dataScopeFilter(JoinPoint joinPoint, Long operationId, String tableAlias) {
        String sqlString;
        if (StringUtils.isNotBlank(tableAlias)) {
            // 拼接 sql（有表别名）
            sqlString = StringUtils.format(" OR {}.customer_id IN ( SELECT customer_id FROM sjmc_sys_customer WHERE operation_center_id = {} ) ",
                    tableAlias, operationId);
        } else {
            // 拼接 sql（无表别名）
            sqlString = StringUtils.format(" OR customer_id IN ( SELECT customer_id FROM sjmc_sys_customer WHERE operation_center_id = {} ) ",
                    operationId);
        }
        // 加入查询参数
        Object params = joinPoint.getArgs()[0];
        if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(OPERATION_SCOPE, " AND " + sqlString.substring(4));
        }
    }

    /**
     * 拼接权限sql前先清空params.dataScope参数防止注入
     */
    private void clearDataScope(final JoinPoint joinPoint) {
        Object params = joinPoint.getArgs()[0];
        if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(OPERATION_SCOPE, "");
        }
    }
}
